package com.xh.bussiness.permission.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.permission.bean.dto.*;
import com.xh.bussiness.permission.bean.request.QueryUserRequest;
import com.xh.bussiness.permission.bean.request.UserRequest;
import com.xh.bussiness.permission.dao.UserMapper;
import com.xh.bussiness.permission.model.Role;
import com.xh.bussiness.permission.model.User;
import com.xh.bussiness.permission.model.UserRole;
import com.xh.bussiness.permission.model.UserSchool;
import com.xh.bussiness.permission.service.IRoleService;
import com.xh.bussiness.permission.service.IUserRoleService;
import com.xh.bussiness.permission.service.IUserSchoolService;
import com.xh.bussiness.permission.service.IUserService;
import com.xh.bussiness.permission.util.UserAuthUtil;
import com.xh.bussiness.system.bean.dto.DictionaryBean;
import com.xh.bussiness.system.bean.request.*;
import com.xh.bussiness.system.constant.UserDataCacheConstant;
import com.xh.bussiness.system.model.Dictionary;
import com.xh.bussiness.system.model.*;
import com.xh.bussiness.system.service.*;
import com.xh.bussiness.thirdapi.LongwenApi;
import com.xh.core.bean.XhPage;
import com.xh.core.exception.XhException;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.core.util.CacheUtils;
import com.xh.core.util.MD5Utils;
import com.xh.core.util.StringUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements IUserService {

    public static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private IUserSchoolService userSchoolService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private IGroupUserService groupUserService;
    @Autowired
    private IDictionaryService dictionaryService;
    @Autowired
    private ICourseSystemService courseSystemService;
    @Autowired
    private IGroupRuleService groupRuleService;
    @Autowired
    private IUserDataPermissionService userDataPermissionService;
    @Autowired
    private IGroupSubjectService groupSubjectService;
    @Autowired
    private IDictionaryRelService dictionaryRelService;

    @Override
    public XhPage queryUserPage(XhPage page, QueryUserRequest bean) {
        return this.dao.queryPageUser(page, bean);
    }

    @Override
    public List<User> queryUserList(QueryUserRequest bean) {
        return this.dao.queryUserList(bean);
    }


    @Override
    public List queryUser(UserRequest bean) {
        QueryWrapper qw = new QueryWrapper<User>();
        this.excludeColumns(qw, "password", "payPassword");
        //拼装条件
        qw = prepareParams(bean, qw);
        qw.eq("sys_user",1);
        return this.dao.selectList(qw);
    }


    @Override
    public User getUserByUsername(String username) {
        QueryWrapper qw = new QueryWrapper<User>();
        //拼装条件
        if (!StringUtils.isEmpty(username)) {
            qw.eq("username", username.trim());
        }

        return this.dao.selectOne(qw);
    }


    @Override
    public User getUserByMobile(String mobile) {
        QueryWrapper qw = new QueryWrapper<User>();
        //拼装条件
        if (!StringUtils.isEmpty(mobile)) {
            qw.eq("mobile", mobile);
        }
        return this.selectFirst(qw);
    }

    @Override
    public User getTeacherUserByMobile(String mobile) {
        QueryWrapper qw = new QueryWrapper<User>();
        //拼装条件
        if (!StringUtils.isEmpty(mobile)) {
            qw.eq("mobile", mobile);
        }
        if (!StringUtils.isEmpty(mobile)) {
            qw.ne("username", "家长");
        }
        return this.dao.selectOne(qw);
    }

    @Override
    public String addUser(UserRequest bean) {
        User user = new User();
        if(StringUtils.isNotEmpty(bean.getId())){
            user.setId(bean.getId());
        }
        user.setUsername(bean.getNickname());
        user.setNickname(bean.getNickname());
        user.setMobile(bean.getMobile());
        user.setHeadUrl(bean.getHeadUrl());
        user.setSex(bean.getSex());
        user.setType(3);
        user.setIsAdmin(bean.getIsAdmin());
        user.setIsFront(bean.getIsFront());
        user.setStatus(bean.getStatus());
        user.setIsTry(bean.getIsTry());
        user.setIdentity(bean.getIdentity());
        user.setSysUser(1);
        user.setIsFront(1);
        user.setIsAdmin(1);
        user.setSource(bean.getSource());
        user.setThirdId(bean.getThirdId());
        this.insert(user);

        user.setPassword(UserAuthUtil.encodePassword(user.getId(), MD5Utils.string2MD5(user.getMobile())));
        this.update(user);

        Teacher teacher = new Teacher();
        teacher.setUserId(user.getId());
        teacher.setName(user.getUsername());
        teacherService.insert(teacher);

        if (!CollectionUtils.isEmpty(bean.getRoleIds())) {
            for (String roleId : bean.getRoleIds()) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);

                userRoleService.insert(userRole);
            }
        }
        if (!CollectionUtils.isEmpty(bean.getSchoolIds())) {
            for (String schoolId : bean.getSchoolIds()) {
                UserSchool userSchool = new UserSchool();
                userSchool.setUserId(user.getId());
                userSchool.setSchoolId(schoolId);

                userSchoolService.insert(userSchool);
            }
        }
        if (!CollectionUtils.isEmpty(bean.getGroupIds())) {
            for (String groupId : bean.getGroupIds()) {
                GroupUser groupUser = new GroupUser();
                groupUser.setUserId(user.getId());
                groupUser.setGroupId(groupId);

                groupUserService.insert(groupUser);
            }
        }
        return null;
    }


    @Override
    public String modifyUser(UserRequest bean) {
        User user = this.getById(bean.getId());
        if (user == null) {
            return "当前用户id不存在";
        }
        if (!bean.getMobile().equals(user.getMobile())) {
            User userByMobile = this.getUserByMobile(bean.getMobile());
            if (userByMobile != null) {
                return "手机号已存在";
            }
            user.setMobile(bean.getMobile());
            user.setPassword(UserAuthUtil.encodePassword(user.getId(), MD5Utils.string2MD5(bean.getMobile())));
        }
        user.setUsername(bean.getNickname());
        user.setNickname(bean.getNickname());
        this.update(user);

        userSchoolService.deleteByUserId(user.getId());
        userRoleService.deleteByUserId(user.getId());
        groupUserService.deleteByUserId(user.getId(), null);

        if (!CollectionUtils.isEmpty(bean.getRoleIds())) {
            for (String roleId : bean.getRoleIds()) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);

                userRoleService.insert(userRole);
            }
        }
        if (!CollectionUtils.isEmpty(bean.getSchoolIds())) {
            for (String schoolId : bean.getSchoolIds()) {
                UserSchool userSchool = new UserSchool();
                userSchool.setUserId(user.getId());
                userSchool.setSchoolId(schoolId);

                userSchoolService.insert(userSchool);
            }
        }
        if (!CollectionUtils.isEmpty(bean.getGroupIds())) {
            for (String groupId : bean.getGroupIds()) {
                GroupUser groupUser = new GroupUser();
                groupUser.setUserId(user.getId());
                groupUser.setGroupId(groupId);

                groupUserService.insert(groupUser);
            }
        }
        return null;
    }


    @Override
    public String deleteUser(String id) {
        User user = this.getById(id);
        if (user == null) {
            return "当前用户id不存在";
        }
        user.deleteById(id);

        userSchoolService.deleteByUserId(user.getId());
        userRoleService.deleteByUserId(user.getId());
        groupUserService.deleteByUserId(user.getId(), null);

        return null;
    }

    @Override
    public Map<String, Object> register(String mobile, String idCard) {
        QueryWrapper userWrapper = new QueryWrapper();
        userWrapper.eq("mobile", mobile);
        User user = this.dao.selectOne(userWrapper);

        //通过身份证查询是否已被注册
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id_card", idCard);
        User existsUser = this.dao.selectOne(queryWrapper);
        if (existsUser != null && user != null) {
            if (!existsUser.getMobile().equals(user.getMobile())) {
                throw new XhException("身份证与手机号不匹配！");
            }
        }
        if (existsUser != null && user == null) {
            throw new XhException("该身份证已被注册");
            //按身份证查出来的用户没有，则按手机号用户进行操作（学生数据第一次注册没有身份证号）
        }
        if (existsUser == null && user != null) {
            existsUser = user;
        }

        Map<String, Object> retMap = reloadUserData(mobile, idCard, existsUser);
        if (MapUtils.isEmpty(retMap)) {
            throw new XhException("请检查龙文教务系统身份证与手机号是否匹配！");
        }
        return retMap;
    }

    @Override
    public Map<String, Object> reloadUserData(String mobile, String idCard, User existsUser) {
        List<Map<String, Object>> userList = LongwenApi.queryUserByIdCardAndMobile(idCard, mobile);
        List<Map<String, Object>> teacherList = LongwenApi.queryTeacherByIdCardAndMobile(idCard, mobile);

        if (CollectionUtils.isEmpty(userList) && CollectionUtils.isEmpty(teacherList)) {
            return new HashMap<>();
        }
        Map<String, Object> retMap = new HashMap<>();
        //合并
        List<Map<String, Object>> allUserList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userList)) {
            allUserList.addAll(userList);
        }
        if (!CollectionUtils.isEmpty(teacherList)) {
            allUserList.addAll(teacherList);
        }

        if (!CollectionUtils.isEmpty(allUserList)) {
            //遍历龙文用户是否存在
            List<UserSchool> savedUserSchools = new ArrayList<>();
            List<UserRole> savedUserRoles = new ArrayList<>();
            int i = 0;
            i:
            for (Map<String, Object> lwUserMap : allUserList) {
                //未被注册
                if (i == 0) {
                    //保存user信息
                    String userIdCard = lwUserMap.get("IDCARD").toString();
                    String userName = lwUserMap.get("NAME").toString();
                    String password = userIdCard.substring(userIdCard.length() - 6);
                    if (existsUser == null) {
                        existsUser = new User();

                        existsUser.setIdCard(userIdCard);
                        existsUser.setUsername(userName);
                        existsUser.setMobile(mobile);
                        existsUser.setSysUser(1);
                        //身份证后四位
                        this.insert(existsUser);
                        //保存密码
                        existsUser.setPassword(UserAuthUtil.encodePassword(existsUser.getId(), MD5Utils.string2MD5(password)));
                        this.update(existsUser);
                    } else {
                        existsUser.setUsername(userName);
                        if (StringUtils.isEmpty(existsUser.getIdCard())) {
                            existsUser.setIdCard(userIdCard);
                        }
                        if (StringUtils.isEmpty(existsUser.getPassword())) {
                            existsUser.setPassword(UserAuthUtil.encodePassword(existsUser.getId(), MD5Utils.string2MD5(password)));
                        }
                        existsUser.setSysUser(1);
                        this.update(existsUser);
                    }
                }
               /* //保存用户与龙文校区关联关系
                UserSchool userSchool = userSchoolService.queryByLongwenUserId(existsUser.getId(), lwUserMap.get("ID").toString());
                if (userSchool == null) {
                    UserSchool uSchool = initUserSchool(lwUserMap, existsUser);
                    userSchoolService.insert(uSchool);
                    savedUserSchools.add(uSchool);
                } else {
                    savedUserSchools.add(userSchool);
                }*/
                //保存对应角色信息
                Object roleId = lwUserMap.get("ROLEID");
                if (roleId != null && roleId != "") {
                    insertUserRole(existsUser, roleId.toString(), savedUserRoles);
                    //如果为教师角色 保存教师数据
                    if (roleId.toString().equals("0")) {
                        Teacher teacher = teacherService.getTeacherByUserId(existsUser.getId());
                        if (teacher == null) {
                            teacher = new Teacher();
                            teacher.setName(existsUser.getUsername());
                            teacher.setUserId(existsUser.getId());
                            teacherService.insert(teacher);

                            existsUser.setSysUser(1);
                            this.update(existsUser);
                        }
                    }
                }
                i++;
            }

            retMap.put("userName", existsUser.getUsername());
            retMap.put("schools", savedUserSchools);
            retMap.put("roles", savedUserRoles);
            retMap.put("password", idCard.substring(idCard.length() - 6));
        }
        return retMap;
    }

    @Override
    public String resetPassword(String userId) {
        User user = this.dao.selectById(userId);
        if (user == null) {
            throw new XhException("用户不存在");
        }
        if (StringUtils.isEmpty(user.getMobile())) {
            throw new XhException("手机号不存在");
        }
        user.setPassword(UserAuthUtil.encodePassword(user.getId(), MD5Utils.string2MD5(user.getMobile())));
        this.update(user);
        return user.getPassword();
    }

    @Override
    public User queryUserDetailById(String userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new XhException("用户不存在");
        }
        user.setUserSchools(userSchoolService.queryUserSchoolByUserId(userId));
        user.setUserRoles(userRoleService.queryUserRoleByUserId(userId));
        user.setUserGroups(groupUserService.queryGroupUserByUserId(userId));
        return user;
    }

    @Override
    public List<UserDataPermissionBean> queryUserDataPermission(String userId) {
        if (StringUtils.isEmpty(userId)) {
            return new ArrayList<>();
        }

        User user = this.getById(userId);
        if (user == null) {
            return new ArrayList<>();
        }
        List<Group> groups = groupUserService.queryAllGroupByUserId(userId);
        if (CollectionUtils.isEmpty(groups)) {
            return new ArrayList<>();
        }
        //数据库格式：math2,english,math需要拆分去重
        String subjects = groups.stream().map(item -> item.getSubjects()).collect(Collectors.joining(","));

        //学段
        //学科
        //      年份 组权限  / 个人权限
        //      年级 组权限  / 个人权限
        List<String> subjectList = Arrays.asList(subjects.split(",")).stream().distinct().collect(Collectors.toList());
        List<Dictionary> allSubject = dictionaryService.queryDictByCodes(subjectList);
        if (CollectionUtils.isEmpty(allSubject)) {
            return new ArrayList<>();
        }
        List<Dictionary> years = dictionaryService.queryDictByTypeCodes(Arrays.asList("YEAR"));
        Map<String, Dictionary> subjectMap = allSubject.stream().collect(Collectors.toMap((item -> item.getCode()), item -> item, (a, b) -> a));
        //获取学科组的数据权限
        List<UserSubjectBean> userSubjectBeans = new ArrayList<>();

        int labelCount;
        for (String subjectCode : subjectList) {
            labelCount = 0;

            UserSubjectBean userSubjectBean = new UserSubjectBean();
            Dictionary subject = subjectMap.get(subjectCode);
            Dictionary gradeRange = dictionaryService.queryGradeRangeBySubjectCode(subjectCode);


            userSubjectBean.setSubjectCode(subjectCode);
            userSubjectBean.setSubjectName(subject.getName());
            userSubjectBean.setGradeRangeCode(gradeRange.getCode());
            userSubjectBean.setGradeRangeName(gradeRange.getName());
            userSubjectBean.setGradeRangeOrderNo(gradeRange.getOrderNo());

            //根据课程体系查基础项
            //所有年级
            List<Dictionary> grades = courseSystemService.queryDictionaryByCourseSystem(subjectCode, "GRADE");
            //所有学期
            List<Dictionary> semesters = courseSystemService.queryDictionaryByCourseSystem(subjectCode, "SEMESTER");
            //所有课程分类
            List<Dictionary> courseTypes = courseSystemService.queryDictionaryByCourseSystem(subjectCode, "COURSE_TYPE");
            //教材版本
            List<Dictionary> bookVersions = courseSystemService.queryDictionaryByCourseSystem(subjectCode, "TEACH_BOOK_VERSION");

            userSubjectBean.setYears(years);
            userSubjectBean.setGrades(grades);
            userSubjectBean.setSemester(semesters);
            userSubjectBean.setCourseTypes(courseTypes);
            userSubjectBean.setBookVersions(bookVersions);

            //组权限
            GroupRule groupRule = groupRuleService.queryGroupRuleBySubjectCodeAndUserId(subjectCode, userId);
            if (groupRule != null) {
                //根据学科查询组权限并去重
                List<String> groupYears = StringUtils.isEmpty(groupRule.getYear()) ? new ArrayList<>() : Arrays.stream(groupRule.getYear().split(",")).distinct().collect(Collectors.toList());
                List<String> groupGradeIds = StringUtils.isEmpty(groupRule.getGradeId()) ? new ArrayList<>() : Arrays.stream(groupRule.getGradeId().split(",")).distinct().collect(Collectors.toList());
                List<String> groupTermIds = StringUtils.isEmpty(groupRule.getTermId()) ? new ArrayList<>() : Arrays.stream(groupRule.getTermId().split(",")).distinct().collect(Collectors.toList());
                List<String> groupBookVersionIds = StringUtils.isEmpty(groupRule.getBookVersionId()) ? new ArrayList<>() : Arrays.stream(groupRule.getBookVersionId().split(",")).distinct().collect(Collectors.toList());
                List<String> groupCourseTypeIds = StringUtils.isEmpty(groupRule.getCourseTypeId()) ? new ArrayList<>() : Arrays.stream(groupRule.getCourseTypeId().split(",")).distinct().collect(Collectors.toList());

                if(groupYears.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "YEAR");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    groupYears = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    groupYears.add("0");
                }
                if(groupGradeIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "GRADE");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    groupGradeIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    groupGradeIds.add("0");
                }
                if(groupTermIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "SEMESTER");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    groupTermIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    groupTermIds.add("0");
                }
                if(groupBookVersionIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "TEACH_BOOK_VERSION");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    groupBookVersionIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    groupBookVersionIds.add("0");
                }
                if(groupCourseTypeIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "COURSE_TYPE");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    groupCourseTypeIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    groupCourseTypeIds.add("0");
                }

                userSubjectBean.setGroupYears(groupYears);
                userSubjectBean.setGroupGrades(groupGradeIds);
                userSubjectBean.setGroupSemester(groupTermIds);
                userSubjectBean.setGroupBookVersions(groupBookVersionIds);
                userSubjectBean.setGroupCourseTypes(groupCourseTypeIds);

                labelCount += groupYears.size() + groupGradeIds.size() + groupTermIds.size() + groupBookVersionIds.size() + groupCourseTypeIds.size();

            }
            //用户权限
            UserDataPermission userDataPermission = userDataPermissionService.queryByUserIdAndSubjectCode(userId, subjectCode);
            if (userDataPermission != null) {
                //根据学科查询用户数据权限并去重
                List<String> userYears = StringUtils.isEmpty(userDataPermission.getYear()) ? new ArrayList<>() : Arrays.stream(userDataPermission.getYear().split(",")).distinct().collect(Collectors.toList());
                List<String> userGradeIds = StringUtils.isEmpty(userDataPermission.getGradeId()) ? new ArrayList<>() : Arrays.stream(userDataPermission.getGradeId().split(",")).distinct().collect(Collectors.toList());
                List<String> userTermIds = StringUtils.isEmpty(userDataPermission.getTermId()) ? new ArrayList<>() : Arrays.stream(userDataPermission.getTermId().split(",")).distinct().collect(Collectors.toList());
                List<String> userBookVersionIds = StringUtils.isEmpty(userDataPermission.getBookVersionId()) ? new ArrayList<>() : Arrays.stream(userDataPermission.getBookVersionId().split(",")).distinct().collect(Collectors.toList());
                List<String> userCourseTypeIds = StringUtils.isEmpty(userDataPermission.getCourseTypeId()) ? new ArrayList<>() : Arrays.stream(userDataPermission.getCourseTypeId().split(",")).distinct().collect(Collectors.toList());
                if(userYears.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "YEAR");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    userYears = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    userYears.add("0");
                }
                if(userGradeIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "GRADE");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    userGradeIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    userGradeIds.add("0");
                }
                if(userTermIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "SEMESTER");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    userTermIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    userTermIds.add("0");
                }
                if(userBookVersionIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "TEACH_BOOK_VERSION");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    userBookVersionIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    userBookVersionIds.add("0");
                }
                if(userCourseTypeIds.contains("0")){
                    //查库
                    QueryWrapper<Dictionary> qw = new QueryWrapper<>();
                    qw.eq("type_code", "COURSE_TYPE");
                    qw.eq("status", 0);
                    qw.orderByAsc("order_no");
                    List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
                    userCourseTypeIds = yearList.stream().map(DictionaryBean::getId).collect(Collectors.toList());
                    userCourseTypeIds.add("0");
                }

                labelCount += userYears.size() + userGradeIds.size() + userTermIds.size() + userBookVersionIds.size() + userCourseTypeIds.size();

                userSubjectBean.setUserYears(userYears);
                userSubjectBean.setUserGrades(userGradeIds);
                userSubjectBean.setUserSemester(userTermIds);
                userSubjectBean.setUserBookVersions(userBookVersionIds);
                userSubjectBean.setUserCourseTypes(userCourseTypeIds);
                userSubjectBean.setLabelCount(labelCount);

            }
            userSubjectBeans.add(userSubjectBean);
        }
        Map<String, Dictionary> gradeRangeMap = dictionaryService.queryDictByTypeCodes(Arrays.asList("GRADE_RANGE")).stream().collect(Collectors.toMap((item -> item.getCode()), item -> item, (a, b) -> a));
        if (!CollectionUtils.isEmpty(userSubjectBeans)) {
            Map<String, List<UserSubjectBean>> userSubjectBeanMap = userSubjectBeans.stream().collect(Collectors.groupingBy(item -> item.getGradeRangeCode()));
            List<UserDataPermissionBean> datas = new ArrayList<>();
            for (String gradeRangeCode : userSubjectBeanMap.keySet()) {
                List<UserSubjectBean> values = userSubjectBeanMap.get(gradeRangeCode);
                Dictionary gradeRange = gradeRangeMap.get(gradeRangeCode);
                UserDataPermissionBean userDataPermission = new UserDataPermissionBean();
                userDataPermission.setGradeRangeCode(gradeRange.getCode());
                userDataPermission.setGradeRangeName(gradeRange.getName());
                userDataPermission.setOrderNo(gradeRange.getOrderNo());
                userDataPermission.setUserSubjectBeans(values);

                datas.add(userDataPermission);
            }
            if (!CollectionUtils.isEmpty(datas)) {
                return datas.stream().sorted(Comparator.comparing(UserDataPermissionBean::getOrderNo)).collect(Collectors.toList());

            }
            return datas;
        }
        return null;
    }

    // 用户数据学科
    @Override
    public List<DictionaryBean> userDataSubjects(String userId) {
        // 用户数据缓存key
        String cacheKey = UserDataCacheConstant.USER_DATA_SUBJECTS_KEY_PREFIX + userId;
        // 查缓存
       /* List<DictionaryBean> cache = cache(userId, cacheKey, new TypeReference<UserDataCacheBean<List<DictionaryBean>>>() {
        });
        if (cache != null) {
            return cache;
        }*/

        // 初始化查询列表
        List<String> subjectCodes = new ArrayList<>();

        // 组学科
        List<GroupSubject> groupSubjects = groupSubjects(userId);
        // 添加查询列表
        if (!groupSubjects.isEmpty()) {
            subjectCodes = groupSubjects.stream().map(GroupSubject::getSubjectCode).collect(Collectors.toList());
        }

        // 用户学科
        UserDataPermissionRequest userDataPermissionRequest = new UserDataPermissionRequest();
        userDataPermissionRequest.setUserId(userId);
        List<UserDataPermission> userDataPermissions = userDataPermissionService.queryUserDataPermission(userDataPermissionRequest);
        // 添加查询列表
        if (!userDataPermissions.isEmpty()) {
            List<String> userSubjectCodes = userDataPermissions.stream().map(UserDataPermission::getSubjectCode).collect(Collectors.toList());
            subjectCodes.addAll(userSubjectCodes);
        }

        // 去重
        subjectCodes = subjectCodes.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList());
        if (subjectCodes.isEmpty()) {
            return new ArrayList<>();
        }

        // 学科
        QueryWrapper<Dictionary> qw = new QueryWrapper<>();
        qw.eq("type_code", "SUBJECT");
        qw.in("code", subjectCodes);
        qw.eq("status", 0);
        qw.orderByAsc("order_no");
        List<DictionaryBean> subjectList = dictionaryService.selectList(qw, DictionaryBean.class);

        // 学段
        qw = new QueryWrapper<>();
        qw.eq("type_code", "GRADE_RANGE");
        qw.eq("status", 0);
        qw.orderByAsc("order_no");
        List<DictionaryBean> gradeRangeList = dictionaryService.selectList(qw, DictionaryBean.class);

        // 把学科组装到学段中
        for (DictionaryBean gradeRange : gradeRangeList) {
            String code = gradeRange.getCode();
            QueryWrapper<DictionaryRel> qwRel = new QueryWrapper<>();
            qwRel.eq("parent_code", code);
            qwRel.eq("child_type_code", "SUBJECT");
            List<String> childCodeList = dictionaryRelService.queryByCondition(qwRel).stream().map(DictionaryRel::getChildCode).collect(Collectors.toList());
            List<DictionaryBean> childSubject = subjectList.stream().filter(subject -> childCodeList.contains(subject.getCode())).map(item->{
                item.setParentCode(code);
                item.setPath(String.format("%s,%s", code, item.getCode()));
                return item;
            }).collect(Collectors.toList());
            gradeRange.setChild(childSubject);
        }

        // 学段去空
        gradeRangeList = gradeRangeList.stream().filter(bean -> !CollectionUtils.isEmpty(bean.getChild())).sorted(Comparator.comparing(DictionaryBean::getOrderNo)).collect(Collectors.toList());

        // 加缓存
       /* Object groupDataVersin = CacheUtils.get(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
        Object userDataVersin = CacheUtils.get(UserDataCacheConstant.USER_DATA_VERSIN_KEY_PREFIX + userId);
        CacheUtils.set(cacheKey, JSON.toJSONString(new UserDataCacheBean<>(groupDataVersin, userDataVersin, gradeRangeList)));*/

        return gradeRangeList;
    }

    // 用户数据权限
    @Override
    public UserDataRuleBean userDataRules(String userId, String subjectCode) {
        // 用户数据缓存key
        String cacheKey = UserDataCacheConstant.USER_DATA_RULES_KEY_PREFIX + userId + "_" + subjectCode;

        // 查缓存
      /* UserDataRuleBean cache = cache(userId, cacheKey, new TypeReference<UserDataCacheBean<UserDataRuleBean>>() {
        });
        if (cache != null) {
            return cache;
        }*/

        // 初始化查询列表
        List<String> years = new ArrayList<>();
        List<String> gradeIds = new ArrayList<>();
        List<String> termIds = new ArrayList<>();
        List<String> bookVersionIds = new ArrayList<>();
        List<String> courseTypeIds = new ArrayList<>();

        // 组权限
        List<GroupRule> groupRules = groupRules(userId, subjectCode);
        // 添加查询列表
        if (!groupRules.isEmpty()) {
            years = groupRules.stream().flatMap(item -> Arrays.stream(item.getYear() != null ? item.getYear().split(",") : new String[0])).collect(Collectors.toList());
            gradeIds = groupRules.stream().flatMap(item -> Arrays.stream(item.getGradeId() != null ? item.getGradeId().split(",") : new String[0])).collect(Collectors.toList());
            termIds = groupRules.stream().flatMap(item -> Arrays.stream(item.getTermId() != null ? item.getTermId().split(",") : new String[0])).collect(Collectors.toList());
            bookVersionIds = groupRules.stream().flatMap(item -> Arrays.stream(item.getBookVersionId() != null ? item.getBookVersionId().split(",") : new String[0])).collect(Collectors.toList());
            courseTypeIds = groupRules.stream().flatMap(item -> Arrays.stream(item.getCourseTypeId() != null ? item.getCourseTypeId().split(",") : new String[0])).collect(Collectors.toList());
        }

        // 用户权限
        UserDataPermission userDataPermission = userDataPermissionService.queryByUserIdAndSubjectCode(userId, subjectCode);
        // 添加查询列表
        if (userDataPermission != null) {
            if (!StringUtils.isEmpty(userDataPermission.getYear())) {
                years.addAll(Arrays.asList(userDataPermission.getYear().split(",")));
            }
            if (!StringUtils.isEmpty(userDataPermission.getGradeId())) {
                String[] split = userDataPermission.getGradeId().split(",");
                List<String> grades = Arrays.asList(split);
                gradeIds.addAll(grades);
            }
            if (!StringUtils.isEmpty(userDataPermission.getTermId())) {
                termIds.addAll(Arrays.asList(userDataPermission.getTermId().split(",")));
            }
            if (!StringUtils.isEmpty(userDataPermission.getBookVersionId())) {
                bookVersionIds.addAll(Arrays.asList(userDataPermission.getBookVersionId().split(",")));
            }
            if (!StringUtils.isEmpty(userDataPermission.getCourseTypeId())) {
                courseTypeIds.addAll(Arrays.asList(userDataPermission.getCourseTypeId().split(",")));
            }
        }

        UserDataRuleBean userDataRules = new UserDataRuleBean();
        // 去重 组装数据
        years = years.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList());
        if (!years.isEmpty()) {
            // 年份
            QueryWrapper<Dictionary> qw = new QueryWrapper<>();
            qw.eq("type_code", "YEAR");
            if (!years.contains("0")){
                qw.in("id", years);
            }
            qw.eq("status", 0);
            qw.orderByAsc("order_no");
            List<DictionaryBean> yearList = dictionaryService.selectList(qw, DictionaryBean.class);
            userDataRules.setYears(yearList);
        }

        // 课程体系专业相关的年级
        QueryWrapper<CourseSystem> csqw = new QueryWrapper<>();
        csqw.eq("relation_type", "GRADE");
        csqw.eq("subject_id", subjectCode);
        List<String> subjectGradeIds = courseSystemService.selectList(csqw, CourseSystem.class).stream().map(CourseSystem::getRelationValue).collect(Collectors.toList());

        // 去重 组装数据
        if(gradeIds.contains("0")){
            gradeIds = subjectGradeIds;
        } else {
            gradeIds = gradeIds.stream().filter(StringUtils::isNotEmpty).filter(subjectGradeIds::contains).distinct().collect(Collectors.toList());
        }

        if (!CollectionUtils.isEmpty(gradeIds)) {
            // 年级
            QueryWrapper<Dictionary> qw = new QueryWrapper<>();
            qw.eq("type_code", "GRADE");
            qw.in("id", gradeIds);
            qw.in("status", 0);
            qw.orderByAsc("order_no");
            List<DictionaryBean> gradeList = dictionaryService.selectList(qw, DictionaryBean.class);
            userDataRules.setGrades(gradeList);
        }
        // 去重 组装数据
        termIds = termIds.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(termIds)) {
            // 学期
            QueryWrapper<Dictionary> qw = new QueryWrapper<>();
            qw.eq("type_code", "SEMESTER");
            if (!termIds.contains("0")){
                qw.in("id", termIds);
            }
            qw.eq("status", 0);
            qw.orderByAsc("order_no");
            List<DictionaryBean> termList = dictionaryService.selectList(qw, DictionaryBean.class);
            userDataRules.setTerms(termList);
        }
        // 去重 组装数据
        bookVersionIds = bookVersionIds.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(bookVersionIds)) {
            // 教材版本
            QueryWrapper<Dictionary> qw = new QueryWrapper<>();
            qw.eq("type_code", "TEACH_BOOK_VERSION");
            if(!bookVersionIds.contains("0")){
                qw.in("id", bookVersionIds);
            }
            qw.eq("status", 0);
            qw.orderByAsc("order_no");
            List<DictionaryBean> bookVersionList = dictionaryService.selectList(qw, DictionaryBean.class);
            userDataRules.setBookVersions(bookVersionList);
        }
        // 去重 组装数据
        courseTypeIds = courseTypeIds.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(courseTypeIds)) {
            // 课程分类
            QueryWrapper<Dictionary> qw = new QueryWrapper<>();
            qw.eq("type_code", "COURSE_TYPE");
            if(!courseTypeIds.contains("0")){
                qw.in("id", courseTypeIds);
            }
            qw.eq("status", 0);
            qw.orderByAsc("order_no");
            List<DictionaryBean> courseTypeList = dictionaryService.selectList(qw, DictionaryBean.class);
            userDataRules.setCourseTypes(courseTypeList);
        }

        // 加缓存
        Object groupDataVersin = CacheUtils.get(UserDataCacheConstant.GROUP_DATA_VERSIN_KEY);
        Object userDataVersin = CacheUtils.get(UserDataCacheConstant.USER_DATA_VERSIN_KEY_PREFIX + userId);
        CacheUtils.set(cacheKey, JSON.toJSONString(new UserDataCacheBean<>(groupDataVersin, userDataVersin, userDataRules)));

        return userDataRules;
    }

    @Override
    public User queryUserByThirdId(String thirdId, Integer source) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("third_id", thirdId);
        qw.eq("source", source);
        return this.selectFirst(qw);
    }

    // 查缓存
    private <T> T cache(String userId, String cacheKey, TypeReference<UserDataCacheBean<T>> type) {
        // 组数据版本key
        String groupDataVersinKey = UserDataCacheConstant.GROUP_DATA_VERSIN_KEY;
        // 用户数据版本key
        String userDataVersinKey = UserDataCacheConstant.USER_DATA_VERSIN_KEY_PREFIX + userId;

        // 取组数据版本和用户数据版本
        Object groupDataVersin = CacheUtils.get(groupDataVersinKey);
        Object userDataVersin = CacheUtils.get(userDataVersinKey);
        // 如果组数据版本和用户数据版本不存在，设置新的版本号（修改组数据或用户数据时会清除掉）
        if (null == groupDataVersin || null == userDataVersin) {
            long timestamp = System.currentTimeMillis();
            if (null == groupDataVersin) {
                CacheUtils.set(groupDataVersinKey, timestamp);
            }
            if (null == userDataVersin) {
                CacheUtils.set(userDataVersinKey, timestamp);
            }
        } else {
            // 如果组数据版本和用户数据版本都存在，取用户数据缓存
            Object o = CacheUtils.get(cacheKey);
            // 判断用户数据缓存是否空
            if (null != o) {
                UserDataCacheBean<T> cache = JSON.parseObject(String.valueOf(o), type);
                groupDataVersin = CacheUtils.get(groupDataVersinKey);
                userDataVersin = CacheUtils.get(userDataVersinKey);
                // 比较版本号，如果是最新，直接返回缓存
                if (cache.getGroupDataVersin().equals(groupDataVersin) && cache.getUserDataVersin().equals(userDataVersin)) {
                    return cache.getData();
                }
            }
        }
        // 否则返回null，触发查数据库的逻辑
        return null;
    }

    // 用户数据组id
    private List<String> userGroupIds(String userId) {
        GroupUserRequest groupUserRequest = new GroupUserRequest();
        groupUserRequest.setUserId(userId);
        List<GroupUser> groupUsers = groupUserService.queryGroupUser(groupUserRequest);
        return groupUsers.stream().map(GroupUser::getGroupId).collect(Collectors.toList());
    }

    // 用户数据组学科
    private List<GroupSubject> groupSubjects(String userId) {
        // 组id
        List<String> groupIds = userGroupIds(userId);
        if (groupIds.isEmpty()) {
            return new ArrayList<>();
        }
        // 组学科
        GroupSubjectRequest groupSubjectRequest = new GroupSubjectRequest();
        groupSubjectRequest.setGroupIds(groupIds);
        return groupSubjectService.queryGroupSubject(groupSubjectRequest);
    }

    // 用户数据组权限
    private List<GroupRule> groupRules(String userId, String subjectCode) {
        // 组id
        List<String> groupIds = userGroupIds(userId);
        if (groupIds.isEmpty()) {
            return new ArrayList<>();
        }
        // 组权限
        GroupRuleRequest groupRuleRequest = new GroupRuleRequest();
        groupRuleRequest.setGroupIds(groupIds);
        groupRuleRequest.setSubjectCode(subjectCode);
        return groupRuleService.queryGroupRule(groupRuleRequest);
    }

    //保存角色信息
    @Override
    public void insertUserRole(User existsUser, String roleId, List<UserRole> savedUserRoles) {
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("third_role_id", roleId);
        Role role = roleService.selectOne(roleQueryWrapper, Role.class);
        if (role == null) {
            log.warn(String.format("role %s is null", roleId));
        } else {
            QueryWrapper userRoleQueryWapper = new QueryWrapper();
            userRoleQueryWapper.eq("role_id", role.getId());
            userRoleQueryWapper.eq("user_id", existsUser.getId());
            UserRole userRole = userRoleService.selectOne(userRoleQueryWapper, UserRole.class);
            //用户角色关系
            if (userRole == null) {
                UserRole saveUserRole = new UserRole();
                saveUserRole.setUserId(existsUser.getId());
                //角色为空则为老师角色
                saveUserRole.setRoleId(role.getId());
                userRoleService.insert(saveUserRole);
                if (savedUserRoles != null) {
                    savedUserRoles.add(saveUserRole);
                }
            } else {
                savedUserRoles.add(userRole);
            }
        }
    }

    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(UserRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        if(StringUtils.isNotEmpty(bean.getUsername())){
            qw.like("username", bean.getUsername());
        }
        return qw;
    }

}
